#include<bits/stdc++.h>
#define ll long long
#define int ll
#define endl "\n"
#define pii pair<int,int>
#define mii map<int,int>
#define umii unordered_map<int,int>
#define vec2(a) vector<vector<a>>
#define vec1(a) vector<a>
#define mp(a,b) make_pair(a,b)
#define max(a,b) (a<b?b:a)
#define min(a,b) (a<b?a:b)
#define INF 0x3f3f3f3f
#define LINF 0x3fffffffffffffff
#define MOD 1000000007
#define i128 __int128
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
std::mt19937_64 rng(std::random_device{}());
std::uniform_int_distribution<std::uint64_t> dist(1,1e18+10);

void init_inv(int size,int mod);
void init_fac(int size,int mod);
int fp(int a,int b,int mod);
int C(int m,int n,int mod);
int A(int m,int n,int mod);
int lcm(int x,int y);
i128 read_int128();
void print_int128(i128 x);
ll read_ll();
void print_ll(ll x);
string read_str();
void print_str(string x);

vector<int> inv;
vector<int> factory;

void solve(){
	string s;
	cin>>s;
	vec1(int) a;
	a.reserve(1e6);
	for(int i=0;i<s.size();i++){
		a.push_back(s[i]-'0');
	}
	vec1(int) hsh(20);
	for(int i=0;i<=9;i++){ //分配哈希值
		hsh[i]=dist(rng);
	}
		//若pre为该区间哈希值得前缀异或和 若区间[l,r]之间所有数字出现次数为偶数次则 pre[r]^pre[l-1]为0
	umii c;
	int now=0,res=0;
	c[0]++;
	for(int i=0;i<a.size();i++){
		now=now^hsh[a[i]];
		res+=c[now];
		c[now]++;
	}
	cout<<res<<endl;
}

signed main(){
    int t;
    t=1;
    while(t--){
        solve();
    }
}

int fp(int a,int b,int mod){
    if(b==0){
        return 1;
    }
    int ret=1;
    while(b){
        if(b&1){
            ret=ret*a%mod;
        }
        a=a*a%mod;
        b>>=1;
    }
    return ret;
}
void init_fac(int size,int mod){
    factory.resize(size+10);
    factory[0]=1;
    for(int i=1;i<=size;i++){
        factory[i]=factory[i-1]*i%mod;
    }
}
void init_inv(int size,int mod){
    inv.resize(size+10);
    inv[1]=1;
    for(int i=2;i<=size;i++){
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    }
}
int C(int m,int n,int mod){
    int ans=1;
    for(int i=1;i<=n;i++){
        ans=ans*((m-i+1)%mod)%mod*inv[i];
    }
    return ans;
}
int A(int m,int n,int mod){
    int ans=1;
    for(int i=1;i<=n;i++){
        ans=ans*(m-i+1)%mod;
    }
    return ans;
}
int lcm(int x,int y){
    return x/__gcd(x,y)*y;
}
////////////////////////////////////////    string类型快读快写          /////////////////////////////
string read_str() {
	char ch=getchar();
	while (ch==' '||ch=='\n'||ch=='\r') {
		ch=getchar();
	}
	string s;
	while (ch!=' '&&ch!='\n'&&ch!='\r'&&ch!=EOF) {
		s+=ch;
		ch=getchar();
	}
	return s;
}
void print_str(string &str) {
	for (char ch:str) {
		putchar(ch);
	}
}
//////////////////////////////////////////   long long快读和快写       /////////////////////////////
long long read_ll() { //快速读取长整型
	char ch=getchar();
	while (!isdigit(ch)&&ch!='-') {
		ch=getchar();
	}
	long long x=0,f=1;
	if (ch=='-') {
		f=-1;
		ch=getchar();
	}
	while (isdigit(ch)) {
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
void print_ll(long long x) { //快速输出长整型
	if (x==0) {
		putchar('0');
		return;
	}
	if (x<0) {
		putchar('-');
		x=-x;
	}
	deque<char> s;
	while (x>0) {
		s.push_front(x%10+'0');
		x/=10;
	}
	while (!s.empty()) {
		putchar(s.front());
		s.pop_front();
	}
	return;
}
//////////////////////////////////////////    大整形的快读快写    /////////////////////////////////////////////////
__int128 read_int128() { //大整形快读
	char ch=getchar();
	while (!isdigit(ch)&&ch!='-') ch=getchar();
	__int128 ans=0;
	__int128 f=1;
	if (ch=='-') {
		f=-1;
		ch=getchar();
	}
	while (isdigit(ch)) {
		ans=ans*10+ch-'0';
		ch=getchar();
	}
	return ans*f;
}
void print_int128(__int128 x) { //大整形快写
	if (x==0) {
		putchar('0');
		return;
	}
	if (x<0) putchar('-'),x=-x;
	char a[100]={0};
    int head=0;
	while (x>0) {
        a[head++]=x%10+'0';
		x/=10;
	}
	while (head--) {
		putchar(a[head]);
	}
}
